package server

import (
	"log"
	"golang.org/x/net/websocket"
	"net/http"
	"fmt"
)

type Server struct {
	pattern string
	messages []*Message
	clients map[int]*Client
	addCh chan *Client
	delCh chan *Client
	sendAllCh chan *Message
	errCh chan error
	doneCh chan bool
	users []*User
}

func NewServer(pattern string) *Server {
	messages := []*Message{}
	clients := make(map[int]*Client)
	addCh := make(chan *Client)
	delCh := make(chan *Client)
	sendAllCh := make(chan *Message)
	doneCh := make(chan bool)
	errCh := make(chan error)
	users := []*User{}

	return &Server{
		pattern,
		messages,
		clients,
		addCh,
		delCh,
		sendAllCh,
		errCh,
		doneCh,
		users,
	}
}
func (this *Server) Add(c *Client) {
	this.addCh <- c
}
func (this *Server) Del(c *Client) {
	this.delCh <- c
}
func (this *Server) SendAll(msg *Message) {
	this.sendAllCh <- msg
}
func (this *Server) Err(err error) {
	this.errCh <- err
}
func (this *Server) Done(bool bool) {
	this.doneCh <- bool
}
func (this *Server) SendPastMessages(c *Client) {
	for _, msg := range this.messages {
		c.Write(msg)
	}
}
func (this *Server) sendAll(msg *Message) {
	for _,c := range this.clients {
		c.Write(msg)
	}
}
func (this *Server) sendOne(c *Client, msg *Message){
	c.Write(msg)
}
func (this *Server) Listen() {
	log.Println("Listening server...")

	onConnected := func(ws *websocket.Conn) {
		defer func() {
			err := ws.Close()
			if err != nil {
				this.errCh <- err
			}
		}()
		client := NewClient(ws, this)
		this.Add(client)

		//发送连接信息
		msg := &Message{"notify",client.id, "","message", "link succesfly",client.id,this.users}
		this.sendOne(client,msg)

		client.Listen()
	}
	http.Handle(this.pattern,websocket.Handler(onConnected))
	log.Println("Created handler")

	for  {
		select {
		case c := <-this.addCh:
			log.Println("added new client")
			this.clients[c.id] = c
			log.Println("当前在线人数:",len(this.clients))
			user := &User{c.id, "",""}
			this.users = append(this.users, user)
			log.Println("当前在线人员信息:",this.users)
			msg := &Message{"system",0, "","online", fmt.Sprintf("%d", len(this.clients)),0,this.users}
			this.sendAll(msg)
			this.SendPastMessages(c)
		case c := <-this.delCh:
			log.Println("delete client")
			delete(this.clients, c.id)
			for k,v := range this.users{
				if v.UserId == c.id {
					this.users = append(this.users[:k], this.users[k+1:]...)
				}
			}
			msg := &Message{"system",0, "","online", fmt.Sprintf("%d", len(this.clients)),0, this.users}
			this.sendAll(msg)
			log.Println("当前在线人数:",len(this.clients))
		case msg := <-this.sendAllCh:
			log.Println("Send all:", msg)
			this.messages = append(this.messages, msg)
			var index int
			for k,v := range this.users{
				if v.UserId == msg.UserId {
					index = k
				}
			}
			this.users[index] = &User{msg.UserId, msg.User, msg.Avatar}
			if msg.ToUserId != 0 {
				this.sendOne(this.clients[msg.ToUserId],msg)
			}else {
				this.sendAll(msg)
			}

		case err := <-this.errCh:
			log.Println("Error:", err.Error())
		case <-this.doneCh:
			return
		}

	}
}